package com.yssoft.service.sales;
 
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collector;
import java.util.stream.Collectors;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSONArray;
import com.yssoft.common.Constants;
import com.yssoft.entity.inventory.TOutstockApply;
import com.yssoft.entity.inventory.TOutstockApplyDetail;
import com.yssoft.entity.sales.TSalesOrder;
import com.yssoft.entity.sales.TSalesOrderDetail;
import com.yssoft.entity.sales.TSellGoods;
import com.yssoft.entity.sales.TSellGoodsDetail;
import com.yssoft.mapper.inventory.TOutstockApplyDetailMapper;
import com.yssoft.mapper.inventory.TOutstockApplyMapper;
import com.yssoft.mapper.inventory.TWarehouseMapper;
import com.yssoft.mapper.sales.TSalesBillMapper;
import com.yssoft.mapper.sales.TSalesOrderDetailMapper;
import com.yssoft.mapper.sales.TSalesOrderMapper;
import com.yssoft.mapper.sales.TSellGoodsDetailMapper;
import com.yssoft.mapper.sales.TSellGoodsMapper;
import com.yssoft.utils.AppUserHelper;
import com.yssoft.utils.CustomDate;
import com.yssoft.utils.JsonUtil;
@Service
public class SaleBillService {
	@Resource
	private TOutstockApplyDetailMapper applyDetailMapper;
	@Resource
	private TOutstockApplyMapper applyMapper;
	@Resource
	private TSellGoodsDetailMapper goodsDetailMapper;
	@Resource
	private TSellGoodsMapper goodsMapper;
	@Resource
	private TSalesOrderDetailMapper orderDetailMapper;
	@Resource
	private TSalesOrderMapper orderMapper;
	@Resource
	private  TSalesBillMapper billMapper;
	@Resource 
	private TWarehouseMapper warehouseMapper;
	@Autowired
	private HttpServletRequest request;
	/**
	 * 
	    * @Title: findOrderPage
	    * @Description: 查看销货订单列表
	    * @param @param currentPage
	    * @param @param pageSize
	    * @param @param param
	    * @param @param request
	    * @param @return    参数
	    * @return List<Map<String,Object>>    返回类型
	    * @throws
	 */
	public List<Map<String, Object>> findOrderPage(Integer currentPage, Integer pageSize, Map<String, Object> param ,
			HttpServletRequest request) {
	 
		/*分页整理*/
		
		if(currentPage!=null && pageSize!=null){
			int start = ((currentPage - 1) * pageSize);
			param.put("start",start);
			param.put("end", pageSize);
		}
		 
		/*当前登录和有效性查询条件整理*/
		param.put("tEId",AppUserHelper.getCurrentCompanyId(request));
		param.put("deleteFlag", 0);
		
		//查询订单列表
		List<  Map<String, Object> > list =billMapper.findOrderPage(param);
		//TODO  详情和detaillsit
		List<  Map<String, Object> > orderMainList=billMapper.findOrderMainDetail(param,list);
	    List<Map<String, Object>>  detailList=billMapper.findOrderMainDetailList(param,list);
	    if(list !=null&& list.size()>0) {
	    	for(Map<String, Object> map  :list) {
	    		Integer orderId=(Integer) map.get("orderId");
	    	 
	    		for (Map<String, Object>   orderMain:orderMainList) {
	    			Integer orderMainId=(Integer) orderMain.get("orderId");
	    			if(orderId==orderMainId) {
	    				map.put("orderMain", orderMain);
	    				List<  Map<String, Object> >  newDetailList=new ArrayList<>();
	    				for(Map<String, Object>   detail :detailList) {
	    					Integer id=(Integer) detail.get("orderId");
	    					if(orderId==id) {
	    						newDetailList.add(detail);
	    					}
	    				}
	    				map.put("detailList", newDetailList);
	    				break;
	    			}
				}
	    	}
	    	
	    }
		return list;
	}
	/**
	 * 
	    * @Title: findBillPage
	    * @Description: 销货单查询列表
	    * @param @param currentPage
	    * @param @param pageSize
	    * @param @param param
	    * @param @param request
	    * @param @return    参数
	    * @return List<Map<String,Object>>    返回类型
	    * @throws
	 */
	public List<Map<String, Object>> findBillPage(Integer currentPage, Integer pageSize, Map<String, Object> param,
			HttpServletRequest request) {
		/*分页整理*/
		if(currentPage!=null && pageSize!=null){
			int start = ((currentPage - 1) * pageSize);
			param.put("start",start);
			param.put("end", pageSize);
		}
		 
		/*当前登录和有效性查询条件整理*/
		param.put("tEId",AppUserHelper.getCurrentCompanyId(request));
		param.put("deleteFlag", 0);
		List<  Map<String, Object> > list =billMapper.findBillPage(param);
		//当前页面id集合
		List<Map<String, Object>>  detailList=billMapper.findBillDetailList(param,list);
		if(list !=null&& list.size()>0) {
	    	for(Map<String, Object> map  :list) {
	    		Integer goodsId=(Integer) map.get("goodsId");
				List<  Map<String, Object> >  newDetailList=new ArrayList<>();
				for(Map<String, Object>   detail :detailList) {
					Integer id=(Integer) detail.get("goodsId");
					if(goodsId==id) {
						newDetailList.add(detail);
					}
				}
				map.put("detailList", newDetailList);
	    	}
	    }
		return list;
	}
	/**
	 * 
	    * @Title: 查看销货订单详情
	    * @Description: TODO(这里用一句话描述这个方法的作用)
	    * @param @param id
	    * @param @return    参数
	    * @return Map<String,Object>    返回类型
	    * @throws
	 */
	public Map<String, Object> findOrderDetail(Map<String, Object> param) {
		 
		List<Map<String, Object>> billDetailList=billMapper.findOrderMainDetail(param,null);
	    Map<String, Object> orderMain=billDetailList.get(0);
	    List<Map<String, Object>>  detailList=billMapper.findOrderMainDetailList(param,billDetailList);
	    orderMain.put("detailList", detailList);
		return orderMain;
	}
	public Map<String, Object> findBillDetail(Map<String, Object> param,HttpServletRequest request) {
		List<Map<String, Object>>  billDetailList=billMapper.findOrderMainDetail(param,null);
		List<Map<String, Object>> detailList=billMapper.findBillDetailList(param,billDetailList);
		
		Map<String, Object> billDetail=billDetailList.get(0);
		billDetail.put("detailList", detailList);
		return billDetail;
	}
	/**
	 * 
	    * @Title: findWarehouseList
	    * @Description: 查看成品参数列表
	    * @param @param param
	    * @param @return    参数
	    * @return Map<String,Object>    返回类型
	    * @throws
	 */
	public List<Map<String, Object>> findWarehouseList(Map<String, Object> param, HttpServletRequest request) {
		/*当前登录和有效性查询条件整理*/
		param.put("companyId",AppUserHelper.getCurrentCompanyId(request));
		param.put("deleteFlag", 0);
		/*成品和启动约束，代码表约束整理*/
		param.put("code", 1);
		param.put("startupStat", "1");
		param.put("classify", Constants.C_MATERIAL); 
		List<Map<String, Object>> list=warehouseMapper.selectWarehouseList(param);
		return list;
	}
	/**
	 * 
    * @Title: createBills
    * @Description: 生成销货单
    * @param @param param
    * @param @param request    参数
    * @return void
    * @throws
	 */
	@Transactional(rollbackFor=RuntimeException.class)
	public Integer  createBills(Map<String, Object> param, HttpServletRequest request) {
		//接受前台并预处理参数
		List<Map > list= new JsonUtil().conversionList(param,"json");	
		Integer orderId=Integer.parseInt(list.get(0).get("orderId").toString());
		//1生成销货单主表
		TSellGoods sellGoods=new TSellGoods();
		sellGoods.setCode("XH"+new Date().getTime());
		sellGoods.setCreateTime(new Date());
		sellGoods.settEId(AppUserHelper.getCurrentCompanyId(request));
		sellGoods.setCreatorName(AppUserHelper.getCurrentUserName(request));
		sellGoods.setDeptName(AppUserHelper.getCurrentDeptName(request));
		sellGoods.setDeptId(AppUserHelper.getCurrentDeptId(request));
		sellGoods.setCreatorId(AppUserHelper.getCurrentUserId(request));
		sellGoods.setDeleteFlag("0");
		sellGoods.settSOId( orderId  );
		goodsMapper.insertSellGoods(sellGoods);
		//2生成申请单主表信息
		Integer goodsId=sellGoods.getId();
		//2.1收集申请单主表信息集合为明细做准备（库id，主单id）
		List<TOutstockApply> appyList=new ArrayList<>();
		//根据库id分组生成多个库id
		Map<Integer, List<TSellGoodsDetail>> wMap = getGoodsDetailList(list, goodsId).stream().collect(Collectors.groupingBy(TSellGoodsDetail ::gettWId ));
								
		for(Entry<Integer, List<TSellGoodsDetail>> e:wMap.entrySet()) {
			Integer warehouseId=e.getKey();
			TOutstockApply appy=new TOutstockApply();
			appy.setCreateTime(new Date());
			appy.settEId(AppUserHelper.getCurrentCompanyId(request));
			appy.setCreatorName(AppUserHelper.getCurrentUserName(request));
			appy.setDeptName(AppUserHelper.getCurrentDeptName(request));
			appy.setDeptId(AppUserHelper.getCurrentDeptId(request));
			appy.setCreatorId(AppUserHelper.getCurrentUserId(request));
			appy.setDeleteFlag("0");
			appy.setCode("CKS"+new Date().getTime());
			appy.setSourceType("3");//1-生产 2-采购 3-销售
			appy.setStat("1");//出库状态：1-待出库 2-已出库
			appy.settWarehouseId(warehouseId);
			appy.settSourceId(goodsId);
			appy.setDeliveryDate(new CustomDate().convert( list.get(0).get("deliveryDate") .toString() )    );
			applyMapper.insert(appy);
			//收集主单id，明细需要插入主单id
			appyList.add(appy);
			 
		}
		
		//生成销货单明细和出货申请明细
		for(Map<String, Object> map:list) {
			//生成销货单明细
			TSellGoodsDetail goodsDetail=new TSellGoodsDetail();
			goodsDetail.setCode("XH"+new Date().getTime());
			goodsDetail.setCreateTime( new Date() );
			goodsDetail.setQuantity(   BigDecimal.valueOf( Long.parseLong( map.get("inNum").toString())  ) );
			goodsDetail.setCreateTime(new Date());
		 	goodsDetail.settEId(AppUserHelper.getCurrentCompanyId(request));
			goodsDetail.setCreatorName(AppUserHelper.getCurrentUserName(request));
			goodsDetail.setDeptName(AppUserHelper.getCurrentDeptName(request));
			goodsDetail.setDeptId(AppUserHelper.getCurrentDeptId(request));
			goodsDetail.setCreatorId(AppUserHelper.getCurrentUserId(request)); 
			goodsDetail.settSGId(  sellGoods.getId()  );
			goodsDetail.settSOId( Integer.parseInt( map.get("orderId").toString()  ) );
			goodsDetail.settSODId( Integer.parseInt( map.get("orderDetailId").toString()  ) );
			goodsDetail.settWId( Integer.parseInt(map.get("warehouseId").toString())  );
	        goodsDetail.setDeleteFlag("0");
	        goodsDetailMapper.insertDetail(goodsDetail);
	        //出货申请明细
	        TOutstockApplyDetail appDetail=new TOutstockApplyDetail();
	        appDetail.setDeleteFlag("0");
			appDetail.setCreateTime(new Date());
			appDetail.settEId(AppUserHelper.getCurrentCompanyId(request));
			appDetail.setCreatorName(AppUserHelper.getCurrentUserName(request));
			appDetail.setDeptName(AppUserHelper.getCurrentDeptName(request));
			appDetail.setDeptId(AppUserHelper.getCurrentDeptId(request));
			appDetail.setCreatorId(AppUserHelper.getCurrentUserId(request));
			
			appDetail.setStat("1");//(出库状态：1-待出库 2-已出库)	,
			appDetail.setSourceType("3");//来源类型：1-生产 2-采购 3-销售 
			appDetail.setpType("1");//1-成品 2-半成品 3-物料
			appDetail.setQuantity(goodsDetail.getQuantity()  );
			appDetail.settPId((Integer) map.get("productId"));
			appDetail.settWarehouseId(  goodsDetail.gettWId());
			appDetail.settSourceId( goodsDetail.getId() );
			//出库申请的主键
			Integer appId=null;
			for(TOutstockApply app:appyList) {
				//根据库id找到申请主单id
				if(goodsDetail.gettWId()==app.gettWarehouseId()) {
					appId=app.getId();
				}
			}
			
			appDetail.settOutstockAppId(appId);
			applyDetailMapper.insert(appDetail);
			
			//收集明细信息更新明细金额和明细数量
			TSalesOrderDetail orderDetail=new TSalesOrderDetail();
			orderDetail.setId( (Integer) map.get("orderDetailId")  );
			orderDetail.setQuantity(appDetail.getQuantity());
			//orderDetail.setSubtotalAmount(BigDecimal.valueOf( Long.parseLong( map.get("totalAmount").toString())  ));
			//orderDetailList.add(orderDetail);
			orderDetail.setOutStockQuantity(BigDecimal.valueOf(0d));
			billMapper.updateOutQuantityByOrderDetailId(orderDetail);
		}
		
		
		return orderId;
	 
	}
	 
	 /**
	  * 
	     * @Title: updateSalesOrder
	     * @Description: 创建销货单之后，需要纠正明细金额，销货单状态
	     * @param @param orderId    参数
	     * @return void    返回类型
	     * @throws
	  */
	public void updateSalesOrder(Integer orderId) {
		//更新订单信息及明细信息
		Integer count=goodsMapper.isCompleted(orderId);
		TSalesOrder order =new TSalesOrder();
		order.setId(orderId);
		order.setSalesOrderStat("1");//销售单状态：见码表 0-待处理 1-已处理,2已完成
		if(count==0) {
			order.setSellGoodsStat("1");//销货单状态：见码表 0-待处理 1-已处理
		} 
		billMapper.updateSalesOrderStat(order);
		//billMapper.updateOrderDetailSubtotalAmount(orderId);
	}
	
	/**
	 * 
	    * @Title: saveOutstockApplyList
	    * @Description: TODO(这里用一句话描述这个方法的作用)
	    * @param @param param
	    * @param @param goodsId
	    * @param @param goodsDetailList    参数
	    * @return void    返回类型
	    * @throws
	 */
	private  void  saveOutstockApplyList( List<Map> list , Integer goodsId, List<TSellGoodsDetail> goodsDetailList ){
	    
		//明细批量处理集合
		List<TOutstockApplyDetail  >  appDetailList=new ArrayList<>();
		//生成出库申请（根据库id划分）包含明细
		List<Map> querygoodsDetailList =goodsDetailMapper.findGoodsDetailList(goodsId);
		
		//取到集合 ，按照库id分组,同时插入数据库主表信息返回主键作为明细外键
		Map<Integer, List<TSellGoodsDetail>> wMap = goodsDetailList.stream().collect(Collectors.groupingBy(TSellGoodsDetail ::gettWId ));
								
		for(Entry<Integer, List<TSellGoodsDetail>> e:wMap.entrySet()) {
			Integer warehouseId=e.getKey();
			TOutstockApply appy=new TOutstockApply();
			appy.setCreateTime(new Date());
			appy.settEId(AppUserHelper.getCurrentCompanyId(request));
			appy.setCreatorName(AppUserHelper.getCurrentUserName(request));
			appy.setDeptName(AppUserHelper.getCurrentDeptName(request));
			appy.setDeptId(AppUserHelper.getCurrentDeptId(request));
			appy.setCreatorId(AppUserHelper.getCurrentUserId(request));
			appy.setDeleteFlag("0");
			appy.setCode("CKSQ"+new Date().getTime());
			appy.setSourceType("3");//1-生产 2-采购 3-销售
			appy.setStat("1");//出库状态：1-待出库 2-已出库
			appy.settWarehouseId(warehouseId);
			List<TSellGoodsDetail> dlist = e.getValue();
			//循环遍历数组
			for (Map map:list) {
				//拿出相同的库id，拿完移除
				if(map.get("warehouseId").toString().equals( warehouseId.toString()  )) {
					appy.setDeliveryDate(  (Date)map.get("deliveryDate")  );
					appy.settSourceId(goodsId);
					list.remove(map);
					//跳出当前循环
					continue;
				}
				
			}
			applyMapper.insert(appy);
			//明细单独处理
			if(goodsDetailList!=null && goodsDetailList.size()>0) {
				for(Map map:querygoodsDetailList) {
					TOutstockApplyDetail appDetail=new TOutstockApplyDetail();
					appDetail.setCreateTime(new Date());
					appDetail.settEId(AppUserHelper.getCurrentCompanyId(request));
					appDetail.setCreatorName(AppUserHelper.getCurrentUserName(request));
					appDetail.setDeptName(AppUserHelper.getCurrentDeptName(request));
					appDetail.setDeptId(AppUserHelper.getCurrentDeptId(request));
					appDetail.setCreatorId(AppUserHelper.getCurrentUserId(request));
					appDetail.settOutstockAppId(appy.getId());
					appDetail.settPId(  (int)map.get("productId") );
					appDetail.setSourceType("3");//来源类型：1-生产 2-采购 3-销售 
					appDetail.setpType("1");//1-成品 2-半成品 3-物料
					appDetail.settWarehouseId( (int) map.get("warehouseId"));
					appDetail.setQuantity(  (BigDecimal)map.get("quantity"));
					appDetail.setStat("1");//(出库状态：1-待出库 2-已出库)	,
					appDetail.settSourceId( (int)map.get("goodsDetailId")   );
					appDetailList.add(appDetail);
				}
			}
			 
		}
		//TODO 暂时这样，待优化
		if(null!=appDetailList && appDetailList.size()>0) {
			for(TOutstockApplyDetail  goodsDetail:appDetailList) {
				applyDetailMapper.insert(goodsDetail);
			}
		}
	 
	}
	/**
	 * 
	    * @Title: getGoodsDetailList
	    * @Description: 提取数据
	    * @param @param param
	    * @param @param goodsId
	    * @param @return    参数
	    * @return List<TSellGoodsDetail>    返回类型
	    * @throws
	 */
	private    List<TSellGoodsDetail> getGoodsDetailList (List<Map> list, Integer goodsId){
		//拆分数据
		List<TSellGoodsDetail> detailList=new ArrayList<>();
		for(Map<String, Object> map:list) {
			TSellGoodsDetail detail=new TSellGoodsDetail();
			detail.settWId( Integer.parseInt(map.get("warehouseId").toString())  );
			detail.setCode("XH"+System.nanoTime());
			detail.setCreateTime( new Date() );
			detail.setQuantity(   BigDecimal.valueOf( Long.parseLong( map.get("inNum").toString())  ) );
			detail.setCreateTime(new Date());
		 	detail.settEId(AppUserHelper.getCurrentCompanyId(request));
			detail.setCreatorName(AppUserHelper.getCurrentUserName(request));
			detail.setDeptName(AppUserHelper.getCurrentDeptName(request));
			detail.setDeptId(AppUserHelper.getCurrentDeptId(request));
			detail.setCreatorId(AppUserHelper.getCurrentUserId(request)); 
			detail.settSOId( Integer.parseInt( map.get("orderId").toString()  ) );
			detail.settSODId( Integer.parseInt( map.get("orderDetailId").toString()  ) );
	        detail.setDeleteFlag("0");
	        
	        detailList.add(detail);
		}
		return detailList;
	}
 
}
